package com.cauli.gateway.satoken;

import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import com.cauli.gateway.config.ThreadPoolConfig;
import com.cauli.gateway.feignService.model.MenuVO;
import com.cauli.gateway.feignService.model.RoleVO;
import com.cauli.gateway.feignService.AccountFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @author Cauli
 * @date 2022/12/13 11:28
 * @description 自定义权限验证接口扩展
 */
@Component
public class StpInterfaceImpl implements StpInterface {
    @Autowired
    private AccountFeignService accountFeignService;

    @Autowired
    private ThreadPoolConfig threadPoolConfig;

    /**
     * 返回一个账号所拥有的权限码集合
     *
     * @param loginId
     * @param loginType
     * @return
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        List<String> res = (List<String>) StpUtil.getTokenSession().get("PERMISSION-LIST");
        if (res == null) {
            CompletableFuture<List<String>> permissionFuture = CompletableFuture.supplyAsync(() -> {
                // 返回此 loginId 拥有的权限列表
                List<MenuVO> menuVOList = accountFeignService.getPermissionList().getData();
                return menuVOList.stream().map(MenuVO::getPermission).collect(Collectors.toList());
            }, threadPoolConfig.USER_ROLE_PERM_THREAD_POOL);
            try {
                return permissionFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        return res;
    }

    /**
     * 返回一个账号所拥有的角色标识集合
     *
     * @param loginId
     * @param loginType
     * @return
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        List<String> res = (List<String>) StpUtil.getTokenSession().get("ROLE-LIST");
        if (res == null) {
            CompletableFuture<List<String>> roleFuture = CompletableFuture.supplyAsync(() -> {
                // 返回此 loginId 拥有的权限列表
                List<RoleVO> roles = accountFeignService.getRoleByUserId(Convert.toLong(loginId)).getData();
                return roles.stream().map(RoleVO::getRoleKey).collect(Collectors.toList());
            }, threadPoolConfig.USER_ROLE_PERM_THREAD_POOL);
            try {
                return roleFuture.get();
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        return res;
    }
}
